<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>DeepClone</title>
    <script src="../js/type.js"></script>
</head>
<body>

    <script>
    /** 变量类型
        js分为基础数据类型和对象类型
        基础数据类型： null undefined string number boolean symbol bigInt
        对象类型： Object Function Array
        区别： 不可变性 基础数据类型实例的方法无法改变原始值
        在js中 变量需要用空间来存储， 内存空间分为两种： 栈内存和堆内存
        栈内存存储基础数据类型 存储的值大小固定，空间较小
        堆内存存储值大小不定， 可动态调整，空间较大，运行效率低，无法直接操作其内部存储，使用引用地址获取（引用地址存储在栈内存中）
        由于栈内存的特性所以导致下面这种情况
    **/
    // var old = [1,2,3,4];
    // var newobj = old;
    // old[0]=5;
    // console.log(old,newobj); // [5,2,3,4], [5,2,3,4]
    // var obj = {};
    // function changeName(obj){
    //     // 此时obj为堆内存引用地址
    //     obj.name = 'name1';
    //     // console.log(obj);
    //     obj = {name: 'name2'};
    //     console.log(obj); // 此时为新的引用地址了
    // }
    // changeName(obj);
    // console.log(type.isObject(obj));
    /*
        浅拷贝： 创建一个新对象， 这个对象有着原始对象的精确拷贝， 如果属性为基本类型，则存储基本类型的值， 如果为引用类型，则存储引用类型的地址
        这导致修改新对象会影响原始对象
        深拷贝： 将一个对象从内存中完整的拷贝一份出来,从堆内存中开辟一个新的区域存放新对象,且修改新对象不会影响原对象
    */
//    var olddata = [1,2,3,4,5];
//    var newdata = type.deepClone(olddata);
//    olddata[0] = 5;
//    console.log(olddata);
//    console.log(newdata);
   // 当前的deepClone方法无法防止 循环引用 目前已经够用了
   // 循环引用的话 解决方案是存起来一个map 每次将属性值作为key存储起来， 如果碰到有的就return
   var map = new Map();
   map.set('name', '213');
   var set = new Set();
   set.add('213123123')
    var obj = {
        name: 1,
        age: 19,
        map: map,
        set: set
    }
    obj.target = obj;
    var newobj = type.deepClone(obj);
    console.log(obj, newobj);

    
    </script>
</body>
</html>